import random

from flask import current_app
from re import match

from flask import session

from info import constants, db
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from info.utils.yuntongxun.sms import CCP
from . import passport_blu
from flask import make_response, jsonify
from flask import request
from info import redis_store
@passport_blu.route("/image_code")
def get_image_code():
    """用来生成图片验证码"""
    # 1、拿到uuid，即image_code_id，并且校验(判空)
    image_code_id=request.args.get('image_code_id')
    if not image_code_id:
        return jsonify(errno=RET.DATAERR, errmsg="缺少参数")
    # 2、生成图片验证码
    name, text, content = captcha.generate_captcha()
    # 3、把图片信息保存到redis，即image_code_id，值是图片验证码的文字内容
    try:
        redis_store.set('Image_code_id'+image_code_id,text,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据库操作错误')
    # 4、返回图片验证码
    response=make_response(content)
    response.headers['Content-Type']='image/jpg'
    return response


@passport_blu.route("/sms_code", methods=["POST"])
def sms_code():
    data_dict=request.json
    mobile = data_dict.get("mobile")  # 获取用户输入的手机号
    image_code = data_dict.get("image_code")  # 获取用户输入的图片验证码内容
    image_code_id = data_dict.get("image_code_id")  # 获取在前端js生成的uuid
    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")

    if not match(r"^1[3578]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式不正确")
    try:
        real_image_code=redis_store.get('Image_code_id' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据库操作失败')
    if not real_image_code:
        return jsonify(errno=RET.NODATA,errmsg='验证码已经过期')
    if real_image_code.decode().lower() !=image_code.lower():
        return jsonify(errno=RET.DATAERR,errmsg='验证码错误')
    try:
        user=User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据库操作失败')
    if user :
        return jsonify(errno=RET.DATAERR,errmsg='手机号码已存在')
    ccp = CCP()
    sms_code=random.randint(100000,999999)
    result=ccp.send_template_sms(mobile, [sms_code, 5], 1)
    if result != 0:
        return jsonify(errno=RET.THIRDERR, errmsg="发送短信失败")
    try:
        redis_store.set('sms_code'+mobile,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="保存短信验证码失败")
    return jsonify(errno=RET.OK, errmsg="发送成功")


@passport_blu.route('/register',methods=['POST'])
def register():
    data_dict=request.json
    mobile = data_dict.get("mobile")  # 获取用户输入的手机号
    sms_code=data_dict.get('sms_code')
    password=data_dict.get('password')
    agree=data_dict.get('agree')

    # 步骤分析：
    # 1、获取参数，判空（接收的参数有：手机号、短信验证码、密码、是否同意协议）
    if not all([mobile,password,sms_code,agree]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")
    if not match(r"^1[3578]\d{9}$", mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机格式不正确")
    # 2、对比redis中的短信验证码和用户输入的是否一致
    try:
        real_sms_code=redis_store.get('sms_code'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库操作失败')
    if not real_sms_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码已经过期')
    if real_sms_code.decode() != sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='验证码错误')
    try:
        redis_store.delete('sms_code'+mobile)
    except Exception as e:
        current_app.logger.error(e)

    # 3、注册本质实际上是在User表中添加一条记录，初始化user模型，设置模型数据(手机、昵称、密码)提交
    user=User()
    user.nick_name = mobile
    user.mobile = mobile
    # 对密码进行处理
    user.password = password
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='数据库操作失败')
    # 4、在session中保存登录状态(包括用户id，手机，昵称)，以便注册后直接登录
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile
    # 5、返回注册成功
    return jsonify(errno=RET.OK, errmsg="注册成功")



@passport_blu.route('/login',methods=['POST'])
def login():
    """
        处理登录请求

        1,获取参数,判空
        2,查询数据库,校验手机是不是在数据库中存在, 如果不存在 return
        3,校验密码
        4,保持登录状态
        5,返回登录成功

        """
    data_dict=request.json
    mobile=data_dict.get('mobile')
    password=data_dict.get('password')
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")
    if not match(r"^1[3578]\d{9}$", mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机格式不正确")
    try:
        user=User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库操作失败')
    if not user:
        return jsonify(errno=RET.DATAERR, errmsg="用户不存在")
    if not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR, errmsg="密码错误")
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile
    from datetime import datetime
    user.last_login = datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        # 这里就可以不用return了，只记录这个错误就行，没有必要阻止用户登录
        current_app.logger.error(e)
    # 5、返回注册成功
    return jsonify(errno=RET.OK, errmsg="登陆成功")


@passport_blu.route('/logout')
def logout():
    session.pop('user_id')
    session.pop('nick_name')
    session.pop('mobile')
    return jsonify(errno=RET.OK, errmsg="退出成功")

